package com.ai.service.impl;

import com.ai.entity.SysRoleEntity;
import com.ai.entity.SysRolePermissionEntity;
import com.ai.entity.SysUserRoleEntity;
import com.ai.exception.BusinessException;
import com.ai.exception.code.BaseResponseCode;
import com.ai.mapper.SysRoleMapper;
import com.ai.mapper.SysRolePermissionMapper;
import com.ai.mapper.SysUserRoleMapper;
import com.ai.service.*;
import com.ai.utils.ConvertUtils;
import com.ai.web.PageResp;
import com.ai.web.request.RoleAddReq;
import com.ai.web.request.RolePageReq;
import com.ai.web.request.RoleUpdateReq;
import com.ai.web.response.DeptRespNodeVO;
import com.ai.web.response.PermissionNodeResp;
import com.ai.web.response.SysRoleResp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 角色管理实现类
 */
@Service
@Slf4j
public class RoleServiceImpl implements RoleService {
    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysRolePermissionMapper sysRolePermissionMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Resource
    private UserRoleService userRoleService;
    @Resource
    private RolePermissionService rolePermissionService;
    @Resource
    private PermissionService permissionService;
    @Resource
    private DeptService deptService;
    @Resource
    private SysRoleDeptService sysRoleDeptService;

    @Override
    public void addRole(RoleAddReq roleAddReq) {
        SysRoleEntity sysRole = ConvertUtils.convert(roleAddReq, SysRoleEntity.class);
        sysRole.setStatus(1);
        sysRoleMapper.insert(sysRole);
        if (!CollectionUtils.isEmpty(roleAddReq.getPermissions())) {
            roleAddReq.getPermissions().forEach(e -> {
                SysRolePermissionEntity sysRolePermission = new SysRolePermissionEntity();
                sysRolePermission.setPermissionId(e);
                sysRolePermission.setRoleId(sysRole.getId());
                sysRolePermissionMapper.insert(sysRolePermission);
            });

        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRole(RoleUpdateReq roleUpdateReq) {
        SysRoleEntity sysRoleOne = sysRoleMapper.selectById(roleUpdateReq.getId());
        if (null == sysRoleOne) {
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        SysRoleEntity sysRole = new SysRoleEntity();
        sysRole.setId(roleUpdateReq.getId());
        sysRole.setName(roleUpdateReq.getName());
        sysRole.setDescription(roleUpdateReq.getDescription());
        sysRoleMapper.updateById(sysRole);

        //删除角色权限关联
        sysRolePermissionMapper.delete(Wrappers.<SysRolePermissionEntity>lambdaQuery().eq(SysRolePermissionEntity::getRoleId, sysRole.getId()));

        if (!CollectionUtils.isEmpty(roleUpdateReq.getPermissions())) {
            roleUpdateReq.getPermissions().forEach(e -> {
                SysRolePermissionEntity sysRolePermission = new SysRolePermissionEntity();
                sysRolePermission.setPermissionId(e);
                sysRolePermission.setRoleId(sysRole.getId());
                sysRolePermissionMapper.insert(sysRolePermission);
            });
        }

    }

    @Override
    public SysRoleResp detailInfo(String id) {
        SysRoleEntity sysRole = sysRoleMapper.selectById(id);
        if (sysRole == null) {
            log.error("传入 的 id:{}不合法", id);
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        SysRoleResp convert = ConvertUtils.convert(sysRole, SysRoleResp.class);
        List<PermissionNodeResp> permissionRespNodes = permissionService.selectAllByTree(1);

        Set<Object> checkList =
                new HashSet<>(rolePermissionService.getPermissionIds(Collections.singletonList(sysRole.getId())));
        setChecked(permissionRespNodes, checkList);
        convert.setPermissionRespNodes(permissionRespNodes);

        List<DeptRespNodeVO> deptRespNodes = deptService.deptTreeList(null, true);
        Set<Object> checkDeptList =
                new HashSet<>(sysRoleDeptService.getDeptIds(sysRole.getId()));
        setCheckedDept(deptRespNodes, checkDeptList);
        convert.setDeptRespNodes(deptRespNodes);
        return convert;
    }

    private void setCheckedDept(List<DeptRespNodeVO> deptRespNodes, Set<Object> checkDeptList) {
        for (DeptRespNodeVO node : deptRespNodes) {
            if (checkDeptList.contains(node.getId())) {
                node.setChecked(true);
            }
            setCheckedDept((List<DeptRespNodeVO>) node.getChildren(), checkDeptList);
        }
    }


    private void setChecked(List<PermissionNodeResp> list, Set<Object> checkList) {
        for (PermissionNodeResp node : list) {
            if (checkList.contains(node.getId())
                    && CollectionUtils.isEmpty(node.getChildren())) {
                node.setChecked(true);
            }
            setChecked((List<PermissionNodeResp>) node.getChildren(), checkList);
        }
    }

    /**
     * 删除角色
     * 删除角色权限
     * 删除角色用户
     *
     * @param id id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deletedRole(String id) {
        //删除角色
        sysRoleMapper.deleteById(id);
        //删除角色权限关联
        sysRolePermissionMapper.delete(Wrappers.<SysRolePermissionEntity>lambdaQuery().eq(SysRolePermissionEntity::getRoleId, id));
        //删除角色用户关联
        sysUserRoleMapper.delete(Wrappers.<SysUserRoleEntity>lambdaQuery().eq(SysUserRoleEntity::getRoleId, id));
    }

    @Override
    public List<SysRoleEntity> getRoleInfoByUserId(String userId) {

        List<String> roleIds = userRoleService.getRoleIdsByUserId(userId);
        if (CollectionUtils.isEmpty(roleIds)) {
            return null;
        }
        return sysRoleMapper.selectBatchIds(roleIds);
    }

    @Override
    public void updateById(SysRoleEntity sysRole) {
        sysRoleMapper.updateById(sysRole);
    }

    @Override
    public PageResp<SysRoleEntity> page(RolePageReq rolePageReq) {
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = Wrappers.lambdaQuery();
        if (!StringUtils.isEmpty(rolePageReq.getRoleName())) {
            queryWrapper.like(SysRoleEntity::getName, rolePageReq.getRoleName());
        }
        if (!StringUtils.isEmpty(rolePageReq.getStatus())) {
            queryWrapper.eq(SysRoleEntity::getStatus, rolePageReq.getStatus());
        }
        queryWrapper.orderByDesc(SysRoleEntity::getCreateTime);
        IPage<SysRoleEntity> iPage = sysRoleMapper.selectPage(new Page<>(rolePageReq.getPage(), rolePageReq.getLimit()), queryWrapper);
        return ConvertUtils.convertPageResp(iPage);
    }
}
